package cn.stronglink.esm27.collection.iot.devices.esm27.request;

import java.util.Arrays;
import java.util.List;

import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;

import cn.stronglink.esm27.collection.iot.devices.esm27.ESM27Server;
import cn.stronglink.esm27.collection.iot.devices.esm27.message.MQMessageOfESM27;
import cn.stronglink.esm27.collection.iot.devices.esm27.request.entity.OpenSerialPortEntity;
import cn.stronglink.esm27.collection.iot.devices.esm27.request.entity.PushSensorDataEntity;
import cn.stronglink.esm27.collection.iot.devices.esm27.task.AutoPushSensorDataService;

@CrossOrigin
@RestController
public class HttpController {
    private Logger logger = Logger.getLogger(getClass());
    private final static String OPEN_SERIAL_PORT_ACTION_CODE_RETURN = "OpenSerialPortReturn"; // MQ中判断消息类型的标识符
    private final static String CLOSE_SERIAL_PORT_ACTION_CODE_RETURN = "CloseSerialPortReturn"; // MQ中判断消息类型的标识符
    private final static String GET_SYSTEM_SERIAL_PORT_LIST_ACTION_CODE_RETURN = "GetSystemSerialPortListReturn"; // MQ中判断消息类型的标识符
    @Autowired
    private ESM27Server esm27Server;
    //	@Autowired
//	protected AutoPushSensorDataTask autoPushSensorDataTask;
    @Value("${esm27.send.interval}")
    private int sendInterval;

    protected AutoPushSensorDataService autoPushSensorDataService;

    @ResponseBody
    @RequestMapping(value = "OpenSerialPort", method = RequestMethod.POST)
    public MQMessageOfESM27 openSerialPort(@RequestBody JSONObject jsonParam) {
        try {
            OpenSerialPortEntity sp = jsonParam.toJavaObject(OpenSerialPortEntity.class);
            logger.infof("==============收到打开端口数据:" + jsonParam.toJSONString());
            // 打开串口
            esm27Server.setSerialPortName(sp.getSerialPortName());
            esm27Server.openSerialPort();
            logger.infof("串口服务已打开，串口号:{}", sp.getSerialPortName());

            // 修改定时推送传感器的时间间隔
            int intervalTime = sp.getAutoPushSensorDataIntervalSeconds() * 1000;
            List<Integer> devIds = sp.getDeviceIds();
            if (devIds == null) {
                devIds = Arrays.asList(new Integer[]{1, 2, 3, 4, 5});
            }

//			autoPushSensorDataTask.setDeviceIds(devIds);
//			autoPushSensorDataTask.setCron(this.time2Cron(intervalTime));
            if (autoPushSensorDataService != null) {
                autoPushSensorDataService.stopAsync();
            }
            autoPushSensorDataService = new AutoPushSensorDataService(esm27Server, devIds, intervalTime, sendInterval);
            autoPushSensorDataService.startAsync();


            PushSensorDataEntity.getInstance().setOpenSerialPortEntity(sp);

            return getResultMessage(OPEN_SERIAL_PORT_ACTION_CODE_RETURN, true, null, null);
        } catch (Exception e) {
            return getResultMessage(OPEN_SERIAL_PORT_ACTION_CODE_RETURN, false, null, e.getMessage());
        }
    }





    /**
     * 关闭窗口
     *
     * @param jsonParam
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "CloseSerialPort", method = RequestMethod.POST)
    public MQMessageOfESM27 closeSerialPort(@RequestBody JSONObject jsonParam) {
        if (PushSensorDataEntity.getInstance().getOpenSerialPortEntity() == null) {
            return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, false, null, "端口未开启");
        }
        try {
            OpenSerialPortEntity sp = jsonParam.toJavaObject(OpenSerialPortEntity.class);
            // 如果要关闭的端口所传的用户Id不等于开启时的用户Id，则抛出异常
            if (!sp.getUserId().equals(PushSensorDataEntity.getInstance().getOpenSerialPortEntity().getUserId())) {
                return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, false, null, "账号不匹配，请用开启时传送的账号关闭端口。");
            }

//			autoPushSensorDataTask.setCron(null);
            if (autoPushSensorDataService != null) {
                autoPushSensorDataService.stopAsync();
            }

            PushSensorDataEntity.getInstance().setOpenSerialPortEntity(null);
            esm27Server.closeSerialPort();
            return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, true, null, null);
        } catch (Exception e) {
            return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, false, null, e.getMessage());
        }
    }



    // 开启定时推送传感器数据
    @ResponseBody
    @RequestMapping(value = "enableTcpPush", method = RequestMethod.POST)
    public MQMessageOfESM27 startAutoPushSensorData(@RequestBody JSONObject jsonParam) {
        try {
            OpenSerialPortEntity sp = jsonParam.toJavaObject(OpenSerialPortEntity.class);
            logger.infof("==============开启TCP定时推送传感器数据:" + jsonParam.toJSONString());
            // 修改定时推送传感器的时间间隔
            int intervalTime = sp.getAutoPushSensorDataIntervalSeconds() * 1000;
            List<Integer> devIds = sp.getDeviceIds();
            if (devIds == null) {
                devIds = Arrays.asList(new Integer[]{1, 2, 3, 4, 5});
            }
            if (autoPushSensorDataService != null) {
                autoPushSensorDataService.stopAsync();
            }
            autoPushSensorDataService = new AutoPushSensorDataService(esm27Server, devIds, intervalTime, sendInterval);
            autoPushSensorDataService.startAsync();
            PushSensorDataEntity.getInstance().setOpenSerialPortEntity(sp);
            return getResultMessage(OPEN_SERIAL_PORT_ACTION_CODE_RETURN, true, null, null);
        } catch (Exception e) {
            return getResultMessage(OPEN_SERIAL_PORT_ACTION_CODE_RETURN, false, null, e.getMessage());
        }
    }

    // 关闭

    @ResponseBody
    @RequestMapping(value = "disableTcpPush", method = RequestMethod.POST)
    public MQMessageOfESM27 stopAutoPushSensorData(@RequestBody JSONObject jsonParam) {
        if (PushSensorDataEntity.getInstance().getOpenSerialPortEntity() == null) {
            return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, false, null, "端口未开启");
        }
        try {
            OpenSerialPortEntity sp = jsonParam.toJavaObject(OpenSerialPortEntity.class);
            // 如果要关闭的端口所传的用户Id不等于开启时的用户Id，则抛出异常
            if (!sp.getUserId().equals(PushSensorDataEntity.getInstance().getOpenSerialPortEntity().getUserId())) {
                return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, false, null, "账号不匹配，请用开启时传送的账号关闭端口。");
            }
//			autoPushSensorDataTask.setCron(null);
            if (autoPushSensorDataService != null) {
                autoPushSensorDataService.stopAsync();
            }
            PushSensorDataEntity.getInstance().setOpenSerialPortEntity(null);
            return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, true, null, null);
        } catch (Exception e) {
            return getResultMessage(CLOSE_SERIAL_PORT_ACTION_CODE_RETURN, false, null, e.getMessage());
        }

    }

//	private TopicSender topicSender = (TopicSender) ContextUtils.getBean("topicSender");

    /**
     * 获取端口列表
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "GetSystemSerialPortList", method = RequestMethod.POST)
    public MQMessageOfESM27 GetSystemSerialPortList() {
//		topicSender.send("dd");
        try {
            List<String> serialPortList = esm27Server.getSerialPortList();
            return getResultMessage(GET_SYSTEM_SERIAL_PORT_LIST_ACTION_CODE_RETURN, true, serialPortList, null);
        } catch (Exception e) {
            return getResultMessage(GET_SYSTEM_SERIAL_PORT_LIST_ACTION_CODE_RETURN, false, null, e.getMessage());
        }
    }

    /**
     * 时间转定时规则字符串
     *
     * @param time 需要定时执行的秒数
     * @return
     */
    private String time2Cron(int time) {
        int minute = time / 60;
        int seconds = time % 60;
        String cron = "0/" + seconds + " 0/" + minute + " * * * ?";
        cron = cron.replace("0/0", "*");
        return cron;
    }

    /**
     * 发送异常信息到MQ
     *
     * @param e
     */
    private MQMessageOfESM27 getResultMessage(String actionCode, boolean isSuccess, Object datas, String errorMessage) {
        MQMessageOfESM27 message = new MQMessageOfESM27();
        message.setActioncode(actionCode);
        message.setTimeStamp(System.currentTimeMillis());
        message.setAwsPostdata(datas);
        message.setIsSuccess(isSuccess);
        if (isSuccess == false) {
            message.setErrorMessage(errorMessage);
        }
        return message;
    }
}
